<?php

namespace IDock\Insurance\ZMBX\Request;

use Exception;
use IDock\Insurance\ZMBX\Response\PremiumInquiryResponse;
use IDock\Insurance\ZMBX\ZMBXEnums;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\Premium\PremiumChargingPileVisitor;
use IDock\Visitor\Premium\PremiumCoverageVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\Premium\PremiumRelationVisitor;

class PremiumInquiryRequest extends AllZMBXRequest
{
    protected $route = 'QuotedPrice.do';

    public $requestCode = 'QuotedPrice';

    protected $response = PremiumInquiryResponse::class;

    protected $urlTip = '报价接口';

    /*** @var  PremiumInquiryVisitor $visitor */
    protected $visitor;

    /**
     * @throws Exception
     */
    public function generate(): array
    {
        $this->setZMBXToken($this->visitor->getExtInfoVisitor()->argc);
        return [
            'businessData' => [
                'policyLocation' => $this->address(),//保单归属地
                'businessType' => 'T',//业务类型
                'contract' => $this->coverageList(),//险种列表
                'accident' => $this->accident(),//意外险信息
                'productPlan' => $this->visitor->getVehicleVisitor()->isNewEnergy ? '1382' : '1379',//机动车 1379 新能源 1382
                'businessNo' => $this->visitor->getExtInfoVisitor()->argc['businessNo'] ?? '',//投保主单号
                'customer' => $this->getCustomerInfo(),
                'insuredObject' => $this->getCarData(),
            ]
        ];
    }

    public function address(): array
    {
        return [
            'province' => $this->visitor->getOwnerVisitor()->provinceCode,
            'city' => $this->visitor->getOwnerVisitor()->cityCode,
            'district' => $this->visitor->getOwnerVisitor()->areaCode,
            'accountUser' => '',
            'netPointCode' => '',
        ];
    }

    /**
     * @throws Exception
     */
    public function getCustomerInfo(): array
    {
        $owner = $this->customerModel($this->visitor->getOwnerVisitor());
        $owner['role'] = '3';
        $applicant = $this->customerModel($this->visitor->getApplicantVisitor());
        $applicant['role'] = '1';
        $insured = $this->customerModel($this->visitor->getInsuredVisitor());
        $insured['role'] = '2';
        return [
            $owner,
            $applicant,
            $insured
        ];
    }

    /**
     * @throws Exception
     */
    private function customerModel(PremiumRelationVisitor $model): array
    {
        $arr = [
            'name' => $model->name,
            'identifyType' => ZMBXEnums::$identifyType[$model->certificateTypeCode] ?? '',
            'identifyNumber' => $model->certificateNo,
            'mobile' => $model->mobile,
            'addr' => $model->address,
            'mailPolicy' => $model->email,
            'type' => $model->typeCode == 'R1' ? '1' : '2',
            'identifyValidDate' => date('Y-m-d H:i:s', strtotime($model->certificateStartDate)),
            'identifyValidEndDate' => $model->certificateEndDate == '2099-12-31' ? '9999/12/31 23:59:59' : date('Y-m-d H:i:s', strtotime($model->certificateEndDate)),
            'jobRisk' => '1',//是否有职业风险 1否 5是
        ];
        if ($arr['type'] == '2') {
            $arr['regisDate'] = date('Y-m-d H:i:s', strtotime($model->certificateEndDate));
            $arr['taxperNumber'] = $model->certificateNo;//纳税人识别号或社会信用代码
        }
        if (empty($arr['identifyType'])) {
            throw new Exception("不支持该证件类型");
        }
        return $arr;
    }

    /**
     * 车辆信息
     * @return array
     * @throws Exception
     */
    private function getCarData(): array
    {
        $carData = $this->visitor->getVehicleVisitor();
        $data = [
            'policyCar' => [
                'vin' => $carData->vin,
                'engine' => $carData->engineNo,
                'plateNo' => $carData->licenseNo,
                'chgOwnerFlag' => ($carData->isTransfer or $carData->isCiTransfer) ? '01' : '0',
                'registerDate' => date('Y-m-d H:i:s', strtotime($carData->firstRegisterDate)),
                'newCarSign' => boolval($carData->isNewVehicle),
                'ecdemicVehicleFlag' => $carData->nonlocalCar,
                'issueDate' => $carData->issueDate ? date('Y-m-d H:i:s', strtotime($carData->issueDate)) : '',
                'carCheckStatus' => ZMBXEnums::$carCheckCode[$this->visitor->getExtInfoVisitor()->carCheckCode] ?? '',
                'carUseType' => ZMBXEnums::$causeType[$carData->causeType] ?? '',
                'motorUsageTypeCode' => ZMBXEnums::$useNatureCode[$carData->useNatureCode] ?? '',
                //车身颜色
                'colorCode' => ZMBXEnums::$vehicleColor[$this->visitor->vehicleVisitor->vehicleColor] ?? '',
            ],
            'simpleStadarCar' => $carData->argc,
        ];

        //if ($this->visitor->getVehicleVisitor()->isCiTransfer and $this->visitor->getVehicleVisitor()->isTransfer === 0) {
        //    $data['splitChgOwner'] = '0';
        //}

        if ($this->visitor->getChargingPileVisitorList()) {
            $list = [];
            /*** @var PremiumChargingPileVisitor $value */
            foreach ($this->visitor->getChargingPileVisitorList() as $value) {
                $yearLimit = $value->chargingPileYearLimit;
                $buyDate = '';
                if ($yearLimit == 'PY1') {
                    $buyDate = date('Y-m-d H:i:s', strtotime('-1 year -6 months'));
                } elseif ($yearLimit == 'PY2') {
                    $buyDate = date('Y-m-d H:i:s', strtotime('-4 years -6 months'));
                } elseif ($yearLimit == 'PY3') {
                    $buyDate = date('Y-m-d H:i:s', strtotime('-5 years -6 months'));
                }
                $list[] = [
                    'chargingPostType' => $value->chargingPileType,
                    'chargingPostCode' => $value->chargingPileCode,
                    'chargingPostAddress' => $value->chargingPileAddress,
                    'chargingPostAddressType' => ZMBXEnums::$chargingPileAddressType[$value->chargingPileAddressType] ?? '',
                    'chargingPostKind' => ZMBXEnums::$chargingPileKind[$value->chargingPileAddressType] ?? '',
                    'buyDate' => $buyDate,
                ];
            }
            $data['charging'] = $list;
        }
        if ($data['policyCar']['chgOwnerFlag'] == '01') {
            $data['policyCar']['transferDate'] = date('Y-m-d H:i:s', strtotime($carData->transferDate));
        }
        if (empty($data['policyCar']['carCheckStatus'])) {
            throw new Exception("不支持该验车状态");
        }
        if (empty($data['policyCar']['carUseType'])) {
            throw new Exception("不支持该车辆用途");
        }

        if ($this->visitor->vehicleVisitor->carCertificateType) {
            $data['policyCar']['certificateType'] = $this->visitor->vehicleVisitor->carCertificateType;
            $data['policyCar']['certificateNo'] = $this->visitor->vehicleVisitor->carCertificateNo;
            $data['policyCar']['certificateDate'] = $this->visitor->vehicleVisitor->carCertificateDate ? date('Y-m-d 00:00:00', strtotime($this->visitor->vehicleVisitor->carCertificateDate)) : '';
            $data['policyCar']['newCarFilingFlag'] = '1';
        }


        return $data;
    }

    /**
     * 险种信息
     * @return array
     */
    private function coverageList(): array
    {
        $list = [];

        $coverageList = $this->visitor->getCoverageVisitorList();
        $coverageList = array_combine(array_column($coverageList, 'coverageCode'), $coverageList);
        $biData = [
            'coverage' => [],
            'plantFormMessageBean' => [
                "Answer" => "",
                "QuerySequenceNo" => "",
                "Question" => ""
            ],
            'contractMain' => [
                'validDate' => $this->visitor->biStartData ? date('Y-m-d H:i:s', strtotime($this->visitor->biStartData)) : '',
                'expiryDate' => $this->visitor->biEndData ? date('Y-m-d H:i:s', strtotime($this->visitor->biEndData)) : '',
                'ReinsuranceFlag' => (string)intval($this->visitor->biEffectFlag),
                'riskCode' => $this->visitor->getVehicleVisitor()->isNewEnergy ? '0365' : '0361',
            ],
            'ApmServiceFeeBean' => ['hopeRate' => $this->visitor->getExtInfoVisitor()->expectedDiscount]
        ];
        foreach ($coverageList as $coverage) {

            /*** @var PremiumCoverageVisitor $coverage */
            //交强险
            if ($coverage->coverageCode == 'C01001') {
                $list[] = [
                    'coverage' => [
                        [
                            "amount" => "200000",
                            "ModeCode" => "",
                            "kindCode" => "BZ",
                            "quantity" => "",
                            "RelatedInd" => "",
                            "Rate" => "",
                            "kindName" => "机动车交通事故责任强制险",
                            "unitAmount" => ""
                        ]
                    ],
                    'plantFormMessageBean' => [
                        "Answer" => "",
                        "QuerySequenceNo" => "",
                        "Question" => ""
                    ],
                    'contractMain' => [
                        'validDate' => $this->visitor->ciStartData ? date('Y-m-d H:i:s', strtotime($this->visitor->ciStartData)) : '',
                        'expiryDate' => $this->visitor->ciEndData ? date('Y-m-d H:i:s', strtotime($this->visitor->ciEndData)) : '',
                        'ReinsuranceFlag' => (string)intval($this->visitor->ciEffectFlag),
                        'riskCode' => '0330',
                    ],
                    //'ApmServiceFeeBean' => ['hopeRate' => $this->visitor->getExtInfoVisitor()->expectedDiscount]
                ];
                continue;
            }

            $one = [
                "amount" => floatval($coverage->amount),
                "kindCode" => ZMBXEnums::$coverageCode[$coverage->coverageCode] ?? '',
                "kindName" => ZMBXEnums::$coverageName[$coverage->coverageCode] ?? '',
                'deductibleRate' => $coverage->deductionRate ? '-' . $coverage->deductionRate : '',
                'quantity' => intval($coverage->quantity),
                'unitAmount' => floatval($coverage->unitAmount)
            ];

            //车损险保额
            if ($one['kindCode'] == '01') {
                $one['amount'] = $this->visitor->vehicleVisitor->negotiatedValue ?: $this->visitor->vehicleVisitor->actualValue;
            }
            //乘客险
            if (in_array($coverage->coverageCode, ['C05001', 'C05002', 'C05003', 'C15001', 'C15002', 'C15003'])) {
                $one['quantity'] = intval($this->visitor->getVehicleVisitor()->vehicleSeat - 1);
                $one['unitAmount'] = floatval($coverage->unitAmount ?: $coverage->amount);
            }
            //司机险
            if (in_array($coverage->coverageCode, ['C04001', 'C04002', 'C04003', 'C14001', 'C14002', 'C14003'])) {
                $one['quantity'] = 1;
                $one['unitAmount'] = floatval($coverage->amount);
            }
            //道路救援特约
            if (in_array($coverage->coverageCode, ['C08001', 'C08002', 'C08003', 'C08004', 'C18001', 'C18002', 'C18003', 'C18004'])) {
                $one['quantity'] = intval($coverage->serviceTimes);
            }

            $biData['coverage'][] = $one;
        }
        if ($this->visitor->biStartData) {
            $list[] = $biData;
        }

        return $list;
    }

    /**
     * 意外险
     * @return array
     */
    private function accident(): array
    {
        $list = [];
        if (!$this->visitor->getNonCarInquiryVisitor()->getNonCarList()) {
            return $list;
        }
        /*** @var NonCarProductVisitor $NonCarProductVisitor */
        foreach ($this->visitor->getNonCarInquiryVisitor()->getNonCarList() as $NonCarProductVisitor) {
            $list[] = [
                'rideRiskCode' => $NonCarProductVisitor->planCode,
                'quantity' => $NonCarProductVisitor->insuredNum,
            ];
        }

        return $list;
    }

}
